/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gameheart.server;

import gameheart.transport.Command;
import gameheart.transport.CommandIds;
import gameheart.transport.CommandMessageTag;
import gameheart.transport.MyException;

/**
 *
 * @author win7
 */
public class ServerController {

    private GameManager _gameManager;
    private ServerAdapterManager _adapterManager;

    public ServerController(GameManager gameManager, ServerAdapterManager adapterManager) {
        _gameManager = gameManager;
        _adapterManager = adapterManager;
    }

    /**
     * xu ly su kien client da ve xong
     * @param adapter : adapter tao ra su kien
     * @param command : lenh tuong ung duoc goi tu client.
     */
    private void DrawedReplyReceived(ServerAdapter adapter, Command command) throws MyException {
        ServerAdapterManager adapterManager = _adapterManager;
        GameManager gameManager = _gameManager;
        System.out.println("Server : nguoi choi vua ve xong " + adapter.getUserName());
        adapterManager.DrawedNotify(adapter);
        if (adapterManager.DrawedAll()) {
            System.out.println("Server : ca 4 nguoi choi da ve xong");
            adapterManager.reSetDrawedNumber();
            int currentUserId = gameManager.getCurrentPlayerID();

            if (gameManager.isRoundtripEnd()) {
                for (int index = 0; index < adapterManager.getCurrentAdapterNumber(); ++index) {
                    adapterManager.getAdapter(index).SendRoundTripEnd(currentUserId);
                    adapterManager.getAdapter(index).SendPointInHand(_gameManager.getPointInHand(index));
                    System.out.println("Đã xong đanh xong mot vong");
                }
            }
            adapterManager.getAdapter(currentUserId).SendPlayRequest();
            //adapterManager.getAdapter(currentUserId).SendPointInHand(_gameManager.getPointInHand(currentUserId));
            if (_gameManager.IsHandEnd() && !_gameManager.isRecentlyDeal()) {
                System.out.println("Server : handEnd.");
                for (int index = 0; index < 4; ++index) {
                    _adapterManager.getAdapter(index).SendCommand(CommandIds.HandEnd, null, null, 0);
                    _adapterManager.getAdapter(index).SendMarkOfPlayers(_gameManager.getDiemTongCongs());
                    ServerCard[][] cards = _gameManager.ChiaBai();
                    _adapterManager.getAdapter(index).sendDealRequest(cards[index]);
                    if (_gameManager.getPassCardDirection() != Direction.None) {
                        _adapterManager.getAdapter(index).SendPassCardRequest(_gameManager.getPassCardDirection());
                    } else {
                        _adapterManager.getAdapter(index).SendPassCardDone(cards[index]);
                    }

                }
                if (_gameManager.getPassCardDirection() == Direction.None) {
                    _adapterManager.getAdapter(_gameManager.getCurrentPlayerID()).SendPlayRequest();
                }
            }
        }
    }

    private void PassCard_Handler(Command command, ServerAdapter adapter) throws MyException, NumberFormatException {
        ServerCard[] cards = new ServerCard[3];
        String[] cardNumber = command.getValuesOfArg(CommandMessageTag.CardNumberTag);
        String[] cardType = command.getValuesOfArg(CommandMessageTag.CardTypeTag);
        for (int index = 0; index < 3; ++index) {
            cards[index] = new ServerCard();
            cards[index].setDiem(Integer.parseInt(cardNumber[index]));
            cards[index].setType(ServerCard.Type.values()[Integer.parseInt(cardType[index])]);
        }
        _gameManager.PassCard(adapter.getUserID(), cards);
        if (_gameManager.IsPassDone()) {
            ServerCard[][] finalCards = _gameManager.GetCards();
            for (int playedIndex = 0; playedIndex < _gameManager.playerNumber; ++playedIndex) {
                _adapterManager.getAdapter(playedIndex).SendPassCardDone(finalCards[playedIndex]);
            }
            _adapterManager.getAdapter(_gameManager.getCurrentPlayerID()).SendPlayRequest();
        }
    }

    private void PlayReplyReceived(ServerAdapter adapter, Command command) throws MyException {
        ServerAdapterManager container = _adapterManager;
        GameManager manager = _gameManager;
        int userId = adapter.getUserID();
        int diem = Integer.parseInt(command.getValueOfArg(CommandMessageTag.CardNumberTag));
        ServerCard.Type type = ServerCard.Type.values()[Integer.parseInt(command.getValueOfArg(CommandMessageTag.CardTypeTag))];
        ServerCard card = new ServerCard();
        card.setDiem(diem);
        card.setType(type);
        System.out.println("Server : co nguoi choi vua danh" + command.getValueOfArg(CommandMessageTag.CardNumberTag));
        if (adapter.getUserID() == manager.getCurrentPlayerID()) {
            switch (manager.playCard(userId, card)) {
                case NuocDiDuocChapNhan: {
                    System.out.println("Server :duoc chap nhan");
                    adapter.SendResultPlay(true);
                    for (int index = 0; index < _adapterManager.getCurrentAdapterNumber(); ++index) {
                        ServerAdapter temptAdapter = _adapterManager.getAdapter(index);
                        temptAdapter.SendDrawMovingCard(card, adapter.getUserID());
                    }
                    break;
                }
                case NuocDiKhongHopLe: {
                    adapter.SendResultPlay(false);
                    break;
                }
                case RoundTripEnd: {
                    adapter.SendResultPlay(true);
                    for (int index = 0; index < _adapterManager.getCurrentAdapterNumber(); ++index) {
                        ServerAdapter temptAdapter = _adapterManager.getAdapter(index);
                        temptAdapter.SendRoundTripEnd(userId);
                    }
                    break;
                }

            }
        }
    }

    public void receiveMessage(ServerAdapter adapter, Command command) throws MyException {
        switch (command.getCommandId()) {
            case CommandIds.playReplyId: {
                PlayReplyReceived(adapter, command);
                break;
            }
            case CommandIds.drawedReplyId: {
                DrawedReplyReceived(adapter, command);
                break;
            }
            case CommandIds.JoinGame: {
                UserJoined_handler(adapter, command);
                break;
            }
            case CommandIds.UserIdOfPlayingUserRequest: {
                String[] argNames = new String[1];
                String[] argValues = new String[1];
                argNames[0] = CommandMessageTag.UserIdTag;
                argValues[0] = String.valueOf(_gameManager.getCurrentPlayerID());
                adapter.SendCommand(CommandIds.UserIdOfPlayingUser, argNames, argValues, 1);
                break;
            }
            case CommandIds.PassCard: {
                PassCard_Handler(command, adapter);
                break;
            }
            case CommandIds.Chat: {
                for (int index = 0; index < 4; ++index) {
                    System.out.println("Server : received chat " + command.getValueOfArg(CommandMessageTag.MessageTag));
                    _adapterManager.getAdapter(index).SendChatMessage(adapter.getUserID(), command.getValueOfArg(CommandMessageTag.MessageTag));
                }
            }

        }
    }

    private void UserJoined_handler(ServerAdapter adapter, Command command) throws MyException {
        adapter.setUserName(command.getValueOfArg(CommandMessageTag.UserNameTag));
        String[] userNames = {"", "", "", ""};
        for (int index = 0; index < _adapterManager.getCurrentAdapterNumber(); ++index) {
            if (_adapterManager.getAdapter(index) != null) {
                userNames[index] = _adapterManager.getAdapter(index).getUserName();
            }
        }
        adapter.SendJoinResult(true);
        adapter.SendUserNames(userNames);
        for (int index = 0; index < _adapterManager.getCurrentAdapterNumber(); ++index) {
            if (_adapterManager.getAdapter(index) != null) {
                _adapterManager.getAdapter(index).SendUserJoinedGameNotify(adapter.getUserID(), command.getValueOfArg(CommandMessageTag.UserNameTag));
            }
        }
        boolean joinedAll = true;
        for (int index = 0; index < _adapterManager.getMaxAdapterNumber(); ++index) {
            if (_adapterManager.getAdapter(index) != null) {
                if (_adapterManager.getAdapter(index).getUserName().length() == 0) {
                    joinedAll = false;
                    break;
                }
            } else {
                joinedAll = false;
                break;
            }
        }

        if (joinedAll) {
            for (int index = 0; index < _adapterManager.getCurrentAdapterNumber(); ++index) {
                _adapterManager.getAdapter(index).SendMarkOfPlayers(_gameManager.getDiemTongCongs());
            }
            ServerCard[][] cards = _gameManager.ChiaBai();

            if (_gameManager.getPassCardDirection() == Direction.None) {
                ServerCard[][] finalCards = _gameManager.GetCards();
                for (int playedIndex = 0; playedIndex < _gameManager.playerNumber; ++playedIndex) {
                    _adapterManager.getAdapter(playedIndex).SendPassCardDone(finalCards[playedIndex]);
                    _adapterManager.getAdapter(_gameManager.getCurrentPlayerID()).SendPlayRequest();
                }

            } else {
                for (int index = 0; index < _adapterManager.getCurrentAdapterNumber(); ++index) {
                    _adapterManager.getAdapter(index).SendCommand(CommandIds.startGame, null, null, 0);
                    _adapterManager.getAdapter(index).sendDealRequest(cards[index]);
                    _adapterManager.getAdapter(index).SendPassCardRequest(_gameManager.getPassCardDirection());

                }
            }
        }
    }
}
